﻿using Prism.Commands;
using Quartz;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using ZYing.QPanel.Helpers;

namespace ZYing.QPanel.ViewModels
{
    public class TriggerItemViewModel : ViewModelBase
    {
        private readonly TriggersViewModel _triggersViewModel;
        public TriggerItemViewModel(TriggerKey key, TriggersViewModel triggersViewModel)
        {
            this.Key = key;
            this._triggersViewModel = triggersViewModel ?? throw new ArgumentNullException(nameof(triggersViewModel));
            this.PauseCommand = new DelegateCommand(Pause, this.CanPause).ObservesProperty(() => State);
            this.ResumeCommand = new DelegateCommand(Resume, this.CanResume).ObservesProperty(() => State);
            this.DeleteCommand = new DelegateCommand(Delete);
        }
        public TriggerKey Key { get; }
        private JobKey _jobKey;

        public JobKey JobKey
        {
            get { return _jobKey; }
            set { SetProperty(ref _jobKey, value); }
        }

        public string Group => Key.Group;
        public string Name => Key.Name;
        private TriggerType _triggerType;

        public TriggerType TriggerType
        {
            get => _triggerType;
            set { SetProperty(ref _triggerType, value); }
        }
        private string _triggerData;
        public string TriggerData
        {
            get => _triggerData;
            set { SetProperty(ref _triggerData, value); }
        }

        private DateTimeOffset? _startTime;

        public DateTimeOffset? StartTime
        {
            get { return _startTime; }
            set { SetProperty(ref _startTime, value); }
        }

        private DateTimeOffset? _endTime;

        public DateTimeOffset? EndTime
        {
            get { return _endTime; }
            set { SetProperty(ref _endTime, value); }
        }

        private DateTimeOffset? _lastFireTime;

        public DateTimeOffset? LastFireTime
        {
            get { return _lastFireTime; }
            set { SetProperty(ref _lastFireTime, value); }
        }

        private DateTimeOffset? _nextFireTime;

        public DateTimeOffset? NextFileTime
        {
            get { return _nextFireTime; }
            set { SetProperty(ref _nextFireTime, value); }
        }
        private TriggerState _state;

        public TriggerState State
        {
            get { return _state; }
            set { SetProperty(ref _state, value); }
        }
        public async Task RefreshStatus()
        {
            var trigger = await this._triggersViewModel.Scheduler.GetTrigger(this.Key);
            if (trigger == null) return;
            this.JobKey = trigger.JobKey;
            this.TriggerType = trigger.GetTriggerType();
            this.TriggerData = GetTriggerData(trigger);
            this.StartTime = trigger.StartTimeUtc;
            this.EndTime = trigger.EndTimeUtc;
            this.LastFireTime = trigger.GetPreviousFireTimeUtc();
            this.NextFileTime = trigger.GetNextFireTimeUtc();
            this.State = await _triggersViewModel.Scheduler.GetTriggerState(this.Key);
        }
        public void Merge(TriggerItemViewModel other)
        {
            if (other == null) return;
            this.JobKey = other.JobKey;
            this.TriggerData = other.TriggerData;
            this.TriggerType = other.TriggerType;
            this.StartTime = other.StartTime;
            this.EndTime = other.EndTime;
            this.LastFireTime = other.LastFireTime;
            this.NextFileTime = other.NextFileTime;
            this.State = other.State;
        }

        private string GetTriggerData(ITrigger trigger)
        {
            switch (trigger)
            {
                case ICronTrigger cron: return cron.CronExpressionString;
                case ISimpleTrigger simple: return simple.RepeatInterval.ToString();
            }
            return trigger.ToString();
        }

        public DelegateCommand PauseCommand { get; }
        public DelegateCommand ResumeCommand { get; }
        public DelegateCommand DeleteCommand { get; }
        private bool CanPause()
        {
            if (this.State != TriggerState.Paused) return true;
            return false;
        }
        public async void Pause()
        {
            await _triggersViewModel.Scheduler.PauseTrigger(this.Key);
            await _triggersViewModel.RefreshStatus();
            NotifyHelper.Success("触发器已暂停");
        }
        private bool CanResume()
        {
            if (this.State == TriggerState.Paused) return true;
            return false;
        }
        public async void Resume()
        {
            await _triggersViewModel.Scheduler.ResumeTrigger(this.Key);
            await _triggersViewModel.RefreshStatus();
            NotifyHelper.Success("触发器已恢复");
        }
        public async void Delete()
        {
            if (MessageHelper.Confirm($"确认要删除触发器【{this.Key}】吗？") == false) return;
            await _triggersViewModel.Scheduler.UnscheduleJob(this.Key);
            await _triggersViewModel.Reload();
            NotifyHelper.Success("触发器已删除");
        }
    }
}
